import numpy as np


def left_eigenvectors(A):
    """
    计算矩阵 A 的左特征向量（左特征向量满足 v^H A = λ v^H）。

    参数
    ----------
    A : (n, n) ndarray
        待分解的方阵。可以是实数或复数矩阵。
    normalize : bool, optional
        是否将左特征向量归一化为 2‑范数为 1（默认 True）。

    返回
    -------
    w : (n,) ndarray
        特征值 λ（复数形式）。
    V_left : (n, n) ndarray
        左特征向量矩阵，每列对应一个左特征向量 v_i。
        若 normalize 为 True，则每列满足 v_i^H v_i = 1。
    """
    # 1. 计算 A 的共轭转置（Hermitian transpose）
    A_H = A.conj().T

    # 2. 对 A_H 求右特征值/特征向量
    #    numpy.linalg.eig 返回 (特征值, 右特征向量矩阵)
    w, V_right = np.linalg.eig(A_H)

    # 3. 右特征向量即为左特征向量（共轭转置后仍是列向量）
    V_left = V_right



    return w, V_left


# ------------------- 示例 -------------------
if __name__ == "__main__":
    # 随机生成一个 4×4 的复数矩阵
    np.random.seed(0)
    A = np.array([
        [2,0,0],
       [ 1,1,0],
        [1,1,2],
    ])

    # 计算左特征向量
    eigvals, left_vecs = left_eigenvectors(A)

    # 打印结果
    print("左特征值 (λ):")
    print(eigvals)
    print("\n左特征向量 (每列对应一个向量):")
    print(left_vecs)

    # 验证：v^H A ≈ λ v^H
    i = 0  # 检查第一个特征对
    v = left_vecs[:, i].reshape(-1, 1)  # 列向量
    lhs = v.conj().T @ A  # 1×n
    rhs = eigvals[i] * v.conj().T  # 1×n
    print("\n验证第 {} 个左特征向量:".format(i))
    print("v^H A =", lhs)
    print("λ v^H =", rhs)
    print("误差 (norm):", np.linalg.norm(lhs - rhs))
